package com.blb.aop.util;


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * 日志通知类
 */
@Aspect
@Component
public class LogAdvise {
    @Pointcut("@annotation(com.blb.aop.util.Mylog)")
    public void pointcut() {

    }


    /**
     * 前置处理
     *
     * @param joinPoint
     */
    @Before("pointcut()")
    public void beforeLog(JoinPoint joinPoint) {
        System.out.println("这是前置通知，开始执行方法：" + joinPoint.getSignature().getName());
    }

    /**
     * 后置处理
     *
     * @param joinPoint
     */
    @After("pointcut()")
    public void afterLog(JoinPoint joinPoint) {
        System.out.println("这是后置通知，执行方法结束" + joinPoint.getSignature().getName());
    }

    /**
     * 异常处理
     *
     * @param joinPoint
     * @param throwable
     */
    @AfterThrowing(pointcut = "pointcut()",throwing = "throwable")
    public void afterThrowingLog(JoinPoint joinPoint, Throwable throwable) {
        System.out.println(joinPoint.getSignature().getName() + "方法出现了异常" + throwable.getMessage());
    }

    /**
     * 方法返回处理
     *
     * @param joinPoint
     */
    @AfterReturning("pointcut()")
    public void afterReturningLog(JoinPoint joinPoint) {

        System.out.println("这是方法返回，执行方法返回" + joinPoint.getSignature().getName());
    }
    @Around("pointcut()")
    public Object aroundLog(ProceedingJoinPoint joinPoint) {
        try {
            String name = joinPoint.getSignature().getName();
            long start = System.currentTimeMillis();
            System.out.println(name + "方法开始执行时间" + LocalDateTime.now());
            //获得方法的参数
            System.out.println("方法的参数");
            Object[] args = joinPoint.getArgs();
            for (Object arg : args) {
                System.out.println(arg);
            }
            //执行原始方法
            Object result = joinPoint.proceed();
            System.out.println("方法返回值为" + result);
            long end = System.currentTimeMillis();
            System.out.println("方法执行结束，耗时：" + (end - start));
            return result;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return null;
    }


}

